package com.spzx.product.service.impl;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.spzx.common.core.exception.ServiceException;
import com.spzx.product.api.domain.ProductSku;
import com.spzx.product.api.vo.ProductSkuVo;
import com.spzx.product.api.vo.SkuPriceVo;
import com.spzx.product.domain.Brand;
import com.spzx.product.domain.Product;
import com.spzx.product.service.*;
import com.spzx.product.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;

@Slf4j
@Service
public class ChannelServiceImpl implements IChannelService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private ICategoryService categoryService;

    @Autowired
    private IProductService productService;
    @Autowired
    private ISkuStockService skuStockService;
    @Autowired
    private IProductDetailsService productDetailsService;

    @Autowired
    private ThreadPoolExecutor threadPoolExecutor;

    @Autowired
    private IProductSkuService productSkuService;





    @Override
    public ItemVo getProductSkuItemVo(Long skuId) {
        // 检查商品SKU是否存在
        String key = "product:sku:data";
        Boolean flag = redisTemplate.opsForValue().getBit(key, skuId);
        if (Boolean.FALSE.equals(flag)) {
            log.error("用户查询商品sku不存在：{}", skuId);
            // 如果商品SKU在Redis中不存在，则抛出异常并返回错误信息
            throw new ServiceException("用户查询商品sku不存在");
        }

        ItemVo itemVo = new ItemVo();

        // 异步获取商品SKU信息，并设置到ItemVo对象中
        CompletableFuture<ProductSku> future = CompletableFuture
                .supplyAsync(
                        () -> {
                            ProductSku productSku = productSkuService.getProductSku(skuId);
                            itemVo.setProductSku(productSku);
                            return productSku;
                        },
                        threadPoolExecutor
                );

        // 根据商品SKU信息异步设置商品详情，包括轮播图和规格值列表
        CompletableFuture<Void> futureProductSku = future.thenAcceptAsync(productSku -> {
                    // 获取商品ID
                    Long productId = productSku.getProductId();
                    // 根据商品ID获取商品信息
                    Product product = productService.getById(productId);

                    // 获取商品轮播图URL列表
                    String[] sliderUrlList = product.getSliderUrls().split(",");
                    // 设置商品轮播图URL列表
                    itemVo.setSliderUrlList(sliderUrlList);

                    // 设置商品规格值列表
                    JSONArray specValueList = JSON.parseArray(product.getSpecValue());
                    itemVo.setSpecValueList(specValueList);
                },
                threadPoolExecutor);

        // 异步获取商品价格信息，并设置到ItemVo对象中
        CompletableFuture<Void> futureSkuPrice = CompletableFuture
                .runAsync(() -> {
                            // 获取商品价格信息
                            SkuPriceVo skuPrice = productSkuService.getSkuPrice(skuId);
                            // 设置商品价格信息
                            itemVo.setSkuPrice(skuPrice);
                        },
                        // 使用自定义线程池
                        threadPoolExecutor);

        // 异步获取商品详情图片，并设置到ItemVo对象中
        CompletableFuture<Void> futureProductDetails = future
                .thenAcceptAsync(productSku -> {
                            // 通过productSku获取productId
                            Long productId = productSku.getProductId();
                            // 获取商品详情图片url列表
                            String[] detailsImageUrlList = productDetailsService.getProductDetails(productId);
                            // 设置商品详情图片url列表
                            itemVo.setDetailsImageUrlList(detailsImageUrlList);
                        },
                        threadPoolExecutor);

        // 异步获取商品规格Map，并设置到ItemVo对象中
        CompletableFuture<Void> futureSkuSpecValue = future
                .thenAcceptAsync(productSku -> {
                    // 通过productSku获取productId
                    Long productId = productSku.getProductId();
                    // 获取商品规格Map
                    Map<String, Long> skuSpecValueMap = productSkuService.getSkuSpecValue(productId);
                    // 设置商品规格Map
                    itemVo.setSkuSpecValueMap(skuSpecValueMap);
                });

        // 异步获取商品库存信息，并设置到ItemVo对象中
        CompletableFuture<Void> futureSkuStock = CompletableFuture
                .runAsync(() -> {
                    // 获取商品库存信息
                    SkuStockVo skuStock = skuStockService.getSkuStock(skuId);
                    // 设置商品库存信息
                    itemVo.setSkuStock(skuStock);
                }, threadPoolExecutor);

        // 等待所有异步任务完成
        // 使用CompletableFuture.allOf等待所有异步任务完成后再继续执行后续逻辑
        CompletableFuture.allOf(
                future,// 获取商品SKU信息
                futureProductSku,// 根据商品SKU信息获取商品详情
                futureSkuPrice,// 获取商品价格信息
                futureProductDetails,// 获取商品详情图片
                futureSkuSpecValue,// 获取商品规格Map
                futureSkuStock// 获取商品库存信息
        ).join(); // 这是一个阻塞操作，程序会在此等待直到所有任务都完成。
        return itemVo;
    }

    @Override
    public IndexDataVo index() {
        // 获取一级类别列表
        List<CategoryVo> levelOneCategory = categoryService.getLevelOneCategory();
        // 获取热销产品列表
        List<ProductSkuVo> topSale = productSkuService.getTopSale();
        // 创建首页数据传输对象
        IndexDataVo indexDataVo = new IndexDataVo();
        // 设置类别列表到首页数据传输对象
        indexDataVo.setCategoryList(levelOneCategory);
        // 设置热销产品列表到首页数据传输对象
        indexDataVo.setProductSkuList(topSale);
        // 返回首页数据
        return indexDataVo;
    }
}
